#include "GrassTerrain.hpp"

namespace phx
{

GrassTerrain::GrassTerrain(const phx::vec2f &size, float subDivisor)
{
	mVertexPositions.reserve(subDivisor * subDivisor);

	const float panelWidth = size.x / subDivisor;
	const float panelHeight = size.y / subDivisor;

	for(unsigned int y = 0; y < size.y; ++y)
	{
		const float panelY = y * panelHeight;
		for(unsigned int x = 0; x < size.x; ++x)
		{
			const float panelX = x * panelWidth;

			phx::vec3f vertexNE(panelX + panelWidth, 0.0f, panelY);
			phx::vec3f vertexNW(panelX, 0.0f, panelY);
			phx::vec3f vertexSW(panelX, 0.0f, panelY + panelHeight);
			phx::vec3f vertexSE(panelX + panelHeight, 0.0f, panelY + panelHeight);

			mVertexPositions.push_back(vertexNE.x); mVertexPositions.push_back(vertexNE.y); mVertexPositions.push_back(vertexNE.z);
			mVertexPositions.push_back(vertexNW.x); mVertexPositions.push_back(vertexNW.y); mVertexPositions.push_back(vertexNW.z);
			mVertexPositions.push_back(vertexSW.x); mVertexPositions.push_back(vertexSW.y); mVertexPositions.push_back(vertexSW.z);

			mVertexPositions.push_back(vertexSW.x); mVertexPositions.push_back(vertexSW.y); mVertexPositions.push_back(vertexSW.z);
			mVertexPositions.push_back(vertexSE.x); mVertexPositions.push_back(vertexSE.y); mVertexPositions.push_back(vertexSE.z);
			mVertexPositions.push_back(vertexNE.x); mVertexPositions.push_back(vertexNE.y); mVertexPositions.push_back(vertexNE.z);
		}
	}

	gl::ArrayObject *arrayObject = new gl::ArrayObject();
	arrayObject->setVertices(mVertexPositions);
	mArrayObjects.push_back(arrayObject);


	mMatricesBuffer.setData(nullptr, 3 * 16 * sizeof(float), gl::UniformBuffer::DYNAMIC);

	glm::mat4 view = glm::lookAt(
		glm::vec3(0.0f, 0.0f, -50.0f),
		glm::vec3(0.0f, 0.0f, 0.0f),
		glm::vec3(0.0f, 1.0f, 0.0f)
		);
	mMatricesBuffer.setSubData(glm::value_ptr(view), sizeof(view), sizeof(float) * 16);

	glm::mat4 proj = glm::perspective(45.0f, 1280.0f / 768.0f, 0.001f, 1000.0f);
	mMatricesBuffer.setSubData(glm::value_ptr(proj), sizeof(proj), 0);

	phx::vec3f mScale(1.0f, 1.0f, 1.0f);

	mModelMatrix = glm::scale(mModelMatrix, glm::vec3(mScale.x, mScale.y, mScale.z));
	mMatricesBuffer.setSubData(glm::value_ptr(mModelMatrix), sizeof(mModelMatrix), sizeof(float) * 16 * 2);
}

void GrassTerrain::render()
{
	glEnable(GL_DEPTH_TEST);
	//glEnable(GL_CULL_FACE);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	phx::Model::shader->shaderObject.use();

	int numMeshes = mArrayObjects.size();
	for(int i = 0; i < numMeshes; ++i)
	{
		mArrayObjects[i]->render();
	}
}

GrassTerrain::~GrassTerrain()
{
	while(!mArrayObjects.empty())
	{
		delete mArrayObjects.back();
		mArrayObjects.pop_back();
	}
}

}